package com.microframework.boot.system.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.microframework.base.core.constants.CacheConstants;
import com.microframework.base.core.model.options.TreeNode;
import com.microframework.base.web.page.PageQuery;
import com.microframework.boot.system.model.domain.Org;
import com.microframework.boot.system.service.IOrgService;
import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class OrgServiceImpl implements IOrgService {


	@Override
	public List<TreeNode<Org>> tree(PageQuery<Org> pageQuery) {
		try {
			String select="select id,parent_id,cn_name,en_name,code,sort ";
			StringBuilder sqlBuilder = new StringBuilder(select+" FROM " + Org.TABLE_NAME + " WHERE 1=1");
			List<Object> params = new ArrayList<>();

			Org query = pageQuery.getQuery();
			if (query != null) {
				// 构建查询条件

				if (StringUtils.hasText(query.getCnName())) {
					sqlBuilder.append(" AND cn_name LIKE ?");
					params.add("%" + query.getCnName() + "%");
				}
				
				if (StringUtils.hasText(query.getEnName())) {
					sqlBuilder.append(" AND en_name LIKE ?");
					params.add("%" + query.getEnName() + "%");
				}
				
				if (StringUtils.hasText(query.getCode())) {
					sqlBuilder.append(" AND code LIKE ?");
					params.add("%" + query.getCode() + "%");
				}
				
				if (StringUtils.hasText(query.getParentId())) {
					sqlBuilder.append(" AND parent_id = ?");
					params.add("" + query.getParentId() + "");
				}
				
				if (StringUtils.hasText(query.getIsDel())) {
					sqlBuilder.append(" AND is_del = ?");
					params.add(query.getIsDel());
				}else {
					sqlBuilder.append(" AND is_del = ?");
					params.add("0");
				}
			}
			else {
				sqlBuilder.append(" AND is_del = ?");
				params.add("0");
			}

			// 设置排序
			String orderBy = StringUtils.hasText(pageQuery.getOrderBy()) ? pageQuery.getOrderBy() : " sort";
			String orderDirection = StringUtils.hasText(pageQuery.getOrderDirection()) ? pageQuery.getOrderDirection()
					: "desc";
			sqlBuilder.append(" ORDER BY " + orderBy + " " + orderDirection);
			
			List<Org> orgs=Org.dao.find(sqlBuilder.toString(), params.toArray());
			
			List<TreeNode<Org>> treeNodes = orgs.stream()
				    .map(org -> {
				    	TreeNode<Org> treeNode=new TreeNode<Org>();
				    	treeNode.setId(org.getId());
				    	treeNode.setParentId(org.getParentId());
				    	treeNode.setLabel(org.getCnName());
				    	treeNode.setExtend(org);
				    	return treeNode;
				    })
				    .collect(Collectors.toList());
			
			return recurOptions(treeNodes);
		} catch (Exception e) {
			log.error("查询组织机构下拉树异常{}", e.getMessage());
			return new LinkedList<TreeNode<Org>>();
		}
	}
	
	public List<TreeNode<Org>> recurOptions(List<TreeNode<Org>> allNodes) {
	    // 1. 创建快速查找映射
	    Map<String, TreeNode<Org>> nodeMap = new HashMap<>();
	    Map<String, List<TreeNode<Org>>> parentChildMap = new HashMap<>();
	    
	    // 2. 构建索引
	    for (TreeNode<Org> node : allNodes) {
	        String id = node.getId();
	        String parentId = node.getParentId();
	        
	        // 存储节点映射
	        nodeMap.put(id, node);
	        
	        // 构建父子关系映射
	        parentChildMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(node);
	    }
	    
	    // 3. 识别根节点（自动处理多种情况）
	    List<TreeNode<Org>> roots = new ArrayList<>();
	    for (TreeNode<Org> node : allNodes) {
	        String parentId = node.getParentId();
	        
	        // 根节点条件：父节点为空/不存在/等于自身ID
	        if (parentId == null || 
	            !nodeMap.containsKey(parentId) || 
	            parentId.equals(node.getId())) {
	            roots.add(node);
	        }
	    }
	    
	    // 4. 递归构建树形结构
	    roots.forEach(root -> buildChildren(root, parentChildMap));
	    return roots;
	}

	private void buildChildren(TreeNode<Org> node, Map<String, List<TreeNode<Org>>> parentChildMap) {
	    String nodeId = node.getId();
	    List<TreeNode<Org>> children = parentChildMap.get(nodeId);
	    
	    if (children != null && !children.isEmpty()) {
	        // 设置子节点并继续递归构建
	        node.setChildren(children);
	        children.forEach(child -> buildChildren(child, parentChildMap));
	    }
	}

	@Override
	public List<Org> loadAll(PageQuery<Org> pageQuery) {
		try {
			String select="select * ";
			StringBuilder sqlBuilder = new StringBuilder(select+" FROM " + Org.TABLE_NAME + " WHERE 1=1");
			List<Object> params = new ArrayList<>();

			Org query = pageQuery.getQuery();
			if (query != null) {
				// 构建查询条件

				if (StringUtils.hasText(query.getCnName())) {
					sqlBuilder.append(" AND cn_name LIKE ?");
					params.add("%" + query.getCnName() + "%");
				}
				
				if (StringUtils.hasText(query.getEnName())) {
					sqlBuilder.append(" AND en_name LIKE ?");
					params.add("%" + query.getEnName() + "%");
				}
				
				if (StringUtils.hasText(query.getCode())) {
					sqlBuilder.append(" AND code LIKE ?");
					params.add("%" + query.getCode() + "%");
				}
				
				if (StringUtils.hasText(query.getParentId())) {
					sqlBuilder.append(" AND parent_id = ?");
					params.add(query.getParentId());
				}
				
				if (StringUtils.hasText(query.getIsDel())) {
					sqlBuilder.append(" AND is_del = ?");
					params.add(query.getIsDel());
				}else {
					sqlBuilder.append(" AND is_del = ?");
					params.add("0");
				}
			}

			// 设置排序
			String orderBy = StringUtils.hasText(pageQuery.getOrderBy()) ? pageQuery.getOrderBy() : " sort";
			String orderDirection = StringUtils.hasText(pageQuery.getOrderDirection()) ? pageQuery.getOrderDirection()
					: "desc";
			sqlBuilder.append(" ORDER BY " + orderBy + " " + orderDirection);
			List<Org> orgs=Org.dao.find(sqlBuilder.toString(), params.toArray());
			return buildTree(orgs);
		} catch (Exception e) {
			log.error("查询异常{}", e.getMessage());
			return new LinkedList<Org>();
		}
	}

	@Override
	public List<Org> loadLazy(PageQuery<Org> pageQuery) {
		try {
			String select="select m.*,IFNULL((SELECT COUNT(id) FROM "+Org.TABLE_NAME+" WHERE parent_id = m.id and is_del=0 ), 0) > 0 AS has_children ";
			StringBuilder sqlBuilder = new StringBuilder(select+" FROM " + Org.TABLE_NAME + " m WHERE 1=1");
			List<Object> params = new ArrayList<>();

			Org query = pageQuery.getQuery();
			if (query != null) {
				// 构建查询条件

				if (StringUtils.hasText(query.getCnName())) {
					sqlBuilder.append(" AND m.cn_name LIKE ?");
					params.add("%" + query.getCnName() + "%");
				}
				
				if (StringUtils.hasText(query.getEnName())) {
					sqlBuilder.append(" AND m.en_name LIKE ?");
					params.add("%" + query.getEnName() + "%");
				}
				
				if (StringUtils.hasText(query.getCode())) {
					sqlBuilder.append(" AND m.code LIKE ?");
					params.add("%" + query.getCode() + "%");
				}
				
				if (StringUtils.hasText(query.getParentId())) {
					sqlBuilder.append(" AND m.parent_id = ?");
					params.add(query.getParentId());
				}
				
				if (StringUtils.hasText(query.getIsDel())) {
					sqlBuilder.append(" AND m.is_del = ?");
					params.add(query.getIsDel());
				}else {
					sqlBuilder.append(" AND m.is_del = ?");
					params.add("0");
				}
			}

			// 设置排序
			String orderBy = StringUtils.hasText(pageQuery.getOrderBy()) ? "m."+pageQuery.getOrderBy() : " m.sort";
			String orderDirection = StringUtils.hasText(pageQuery.getOrderDirection()) ? pageQuery.getOrderDirection()
					: " asc ";
			sqlBuilder.append(" ORDER BY " + orderBy + " " + orderDirection);
			return Org.dao.find(sqlBuilder.toString(), params.toArray());
		} catch (Exception e) {
			log.error("查询异常{}", e.getMessage());
			return new LinkedList<Org>();
		}
	}
	
	public List<Org> buildTree(List<Org> nodes) {
	    // 1. 创建快速查找映射表
	    Map<String, Org> nodeMap = new HashMap<>();
	    Map<String, List<Org>> parentChildMap = new HashMap<>();
	    
	    // 2. 构建索引
	    for (Org node : nodes) {
	        String nodeId = node.getId();
	        String parentId = node.getParentId();
	        
	        // 存储节点映射
	        nodeMap.put(nodeId, node);
	        
	        // 构建父子关系映射
	        parentChildMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(node);
	    }
	    
	    // 3. 识别根节点（没有父节点或父节点不存在）
	    List<Org> roots = new ArrayList<>();
	    for (Org node : nodes) {
	        String parentId = node.getParentId();
	        
	        // 根节点条件：父节点为空、不存在或指向自身（根据业务需求调整）
	        if (parentId == null || 
	            !nodeMap.containsKey(parentId) || 
	            parentId.equals(node.getId())) {
	            roots.add(node);
	        }
	    }
	    
	    // 4. 递归构建树形结构
	    roots.forEach(root -> buildTreeRecursive(root, parentChildMap));
	    
	    return roots;
	}

	private void buildTreeRecursive(Org node, Map<String, List<Org>> parentChildMap) {
	    String nodeId = node.getId();
	    List<Org> children = parentChildMap.get(nodeId);
	    
	    if (children != null && !children.isEmpty()) {
	        // 设置子节点并继续递归构建
	        node.setChildren(children);
	        children.forEach(child -> buildTreeRecursive(child, parentChildMap));
	    }
	}

    @Cacheable(value = CacheConstants.SYS_CACHES, key = "#id", sync = true)
	@Override
	public Org findById(String id) {
        log.info("缓存未命,从数据库加载数据，ID: {}", id); // 只有缓存未命中时才会执行
		return Org.dao.findById(id);
	}
}
